const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
const obj = {
    name: 'ck',
    age: 20,
    date: new Date(),
    regExp: /\s+/gi,
    unde: undefined,
    child: {
        name: 'ck',
        age: 20,
        date: new Date(),
        regExp: /\s+/gi,
        cars: ['BMW', 'BENZ', 'AUDI']
    }
}

// JSON拷贝方式
// const obj1 = JSON.parse(JSON.stringify(obj))
// console.log(obj1)
// 这样拷贝的有问题， 就是在Date() 方法和regExp中， 都会将其作为函数直接执行了


// 简单的forin循环， 是个浅拷贝
function flowCloneV1(obj) {
    const newObj = {}
    for (const objKey in obj) {
        newObj[objKey] = obj[objKey]
    }
    // console.log(newObj)
    return newObj
}

// 这样的拷贝， regExp是对的， 但是date还是直接执行了
// obj.obj = obj
// const newObj = flowCloneV1(obj)
// newObj.name = '0000000000'
// newObj.child.name = '1111111111'
// console.log(obj['name']) // 还是ck 没有被上面重新赋值改变 所以 这里是浅拷贝
// console.log(obj.child.name);// 1111111111 不是 ck了 所以 这里没有被深拷贝 还是浅拷贝


function deepCloneV2(obj) {
    const newObj1 = {}
    for (const objKey in obj) {
        if (obj.hasOwnProperty(objKey) && typeof obj[objKey] === 'object') {
            deepCloneV2(obj[objKey])
        } else {
            newObj1[objKey] = obj[objKey]
        }
    }
    // console.log(newObj);
    return newObj1
}

// 其他的是没什么问题了， 但是regExp还是会有问题
const newObj = deepCloneV2(obj)
// newObj.name = '0000000000'
// newObj.child.name = '1111111111'
// console.log(obj['name']) // 还是ck 没有被上面重新赋值改变 所以 这里是浅拷贝
// console.log(obj.child.name);// 1111111111 不是 ck了 所以 这里没有被深拷贝 还是浅拷贝


//上面的拷贝数组会有问题， 就是数组还是也会被转换成一个对象
// 兼容数组， 上面的即使数组也被拷贝了， 但是， 拷贝的是浅拷贝
function deepCloneV3(obj) {
    if (typeof obj === 'object') {
        const newOutput = Array.isArray(obj) ? [] : {}
        for (const objKey in obj) {
            // 这里是要判断， 当前对象是否有给定的key，防止没有的时候发生异常
            if (obj.hasOwnProperty(objKey)) {
                newOutput[objKey] = obj[objKey]
            }
        }
        return newOutput
    } else {
        return obj
    }
}

deepCloneV3(arr)
// 如果obj.obj = obj 会形成一个环， 然后这个环会导致里面的引用数据无法被拷贝
// 例如下面的， cars 就无法被深拷贝
// obj.obj = obj
// deepCloneV3(obj)


// 解决环 存在时候 无法拷贝的问题
function deepCloneV4(target, hash = new WeakMap()) {
    if (hash.has(target)) return hash.get(target)
    const newTarget = Array.isArray(target) ? [] : {}
    hash.set(target, newTarget)
    for (const targetKey in target) {
        if (target.hasOwnProperty(targetKey) && typeof target[targetKey] === 'object') {
            deepCloneV4(target[targetKey], hash)
        } else {
            newTarget[targetKey] = target[targetKey]
        }
    }
    // console.log(newTarget)
    return newTarget
}

// obj.obj = obj
// deepCloneV4(obj)




